﻿using System.Net;
using System;
using System.Serialization;
using System.Collections;

namespace Db7.SS
{
    public static class Remote
    {
        public static void Invoke(RemoteCallSettings remoteSettings)
        {
            XmlHttpRequest req = new XmlHttpRequest();
            string method = remoteSettings.PreserveState? "POST" : "GET";
            string postInfo = null;
            
            string objectTypeName = remoteSettings.Obj.GetType().FullName;
            
            req.Open(method, "Db7.Invoke?M=" + remoteSettings.MethodName + "&T=" + objectTypeName);
            if (remoteSettings.PreserveState)
            {
                //string content = Json.Stringify(remoteSettings.Obj);
                CompactJSONSerializer compactJson = new CompactJSONSerializer();
                string content = compactJson.Serialize(remoteSettings.Obj);
                postInfo = "D=" + content;
                req.SetRequestHeader("Content-type", "application/x-www-form-urlencoded");
                req.SetRequestHeader("Content-length", content.Length.ToString());
                req.SetRequestHeader("Connection", "close");
            }
            req.OnReadyStateChange = delegate()
            {
                if (req.ReadyState == ReadyState.Loaded)
                {
                    object obj = Json.Parse(req.ResponseText);
                    Util.Merge(obj, remoteSettings.Obj);
                    if (remoteSettings.CallbackOnSuccess != null)
                    {
                        remoteSettings.CallbackOnSuccess();
                    }
                    
                }
            };
            if (remoteSettings.PreserveState)
            {
                req.Send(postInfo);
            }
            else
            {
                req.Send();
            }

        }

        
    }

    public class RemoteCallSettings
    {

        public RemoteCallSettings(object thisObj)
        {
            //Script.Eval("debugger;");
            object obj = Script.Eval("arguments.callee.caller");
            this.Obj = thisObj;
            string callerFn = obj.ToString();
            MethodName = Util.SubstringBetweenFirst(callerFn, "$").AndFirst("(");
        }

        public object Obj;
        public string MethodName;
        public bool PreserveState;
        public Action CallbackOnSuccess;
    }

    
    
}
